#/usr/bin/python
# -*- coding: utf-8 -*-

import os
import copy
import cPickle as pickler

# General:
FLOAT = "float64"
DEBUG = True

# Mesh:
NDOFS_PER_NODE = 6
MESH_INTERFACING = "nastran"
RUN_THIRD_SOFTWARE = False


# Solver:
CONSTRAINTS = 'lagrange multipliers'

# Parallel computing:
MAX_PROC = 50
PARALLEL = False

# Domain decomposition:


# Path of temp Directory:
path = os.path.abspath(__file__)
head,tail = os.path.split(path)
TEMP = os.path.join(head,'temp'+os.sep)
TEMPFILE = TEMP + 'param.pickle'

def load():
    try:
        return pickler.load(file(TEMPFILE,'rb'))
    except:
        p = Parameters()
        pickler.dump(p,file(TEMPFILE,'wb'))
        return p

class Parameters():
    
    def __init__(self):
        
        self.DECIMALS = 3
        self.FLOAT = FLOAT
        self.DEBUG = DEBUG
        self.NDOFS_PER_NODE = NDOFS_PER_NODE
        self.MESH_INTERFACING = MESH_INTERFACING
        self.RUN_THIRD_SOFTWARE = RUN_THIRD_SOFTWARE
        self.CONSTRAINTS = CONSTRAINTS
        self.MAX_PROC = MAX_PROC
        self.PARALLEL = PARALLEL
        
        # output format:
        self.FIELDS_FORMAT = 'VTK'
        self.QOI_FORMAT = 'CSV'
        
        # output selection:
        self.OUTPUT_FIELDS = [] #('dof','012345','incr/mode'),('force','012345','incr/iter') selection of field output with levels of extraction (separated by /): 
                                                                     # 'step': per step
                                                                     # 'incr': per increment 
                                                                     # 'iter': per iteration
                                                                     # 'mode': for each calculated mode
                                                                     # if none, default is 'incr'
        self.POINTS_OF_INTEREST = {'dummy' : [0,(0.0,0.0,0.0)],
                                   'set1': [0,1,2,3],
                                   }  # lists of user identifiers of nodes or tuples of coordinates 
        self.OUTPUT_QOI = [] # ('error','iter'),('dof','set1','012','incr'),('force','set1','012','incr') selection of Quantities Of Interest 
        
        self.UPDATE_DOFS = True
        self.UPDATE_INPUTFILE = True
        self.READ_OPERATORS = True
        self.WORKDIR = copy.copy(TEMP)
        self.TEMP = TEMP
        # ...
        
    def __str__(self):
        
        m = 'CURRENT SETTING:\n'
        for attr in self.__dict__.keys():
            m += str(attr) + ' = ' + str(getattr(self,attr)) + '\n'
        
        return m
    
    def getOutputFields(self, level=None):
        
        fields = []
        components = []
        for field in self.OUTPUT_FIELDS:
            if level:
                if level in field[2]:
                    fields.append(field[0])
                    components.append(field[1])
            else:
                fields.append(field[0])
                components.append(field[1])
                
        return tuple(fields), tuple(components)
    
    def getOutputQOI(self, level=None, qoirequest=None):
        
        qois = []
        args = []
        if level:
            for qoi in self.OUTPUT_QOI:
                if qoirequest:
                    if qoi[0]==qoiresquest: continue
                    
                if level in qoi[-1]:
                    qois.append(qoi[0])
                    if len(qoi)>2:
                        args.append(qoi[1:-1])
                    else:
                        args.append(None)
        elif qoirequest:
            for qoi in self.OUTPUT_QOI:
                if qoi[0]==qoirequest:
                    qois=qoi[0]
                    if len(qoi)>2:
                        args=qoi[1:-1]
                    else:
                        args=None
                    return args
        
        else:
            for qoi in self.OUTPUT_QOI:
                qois.append(qoi[0])
                if len(qoi)>2:
                    args.append(qoi[1:-1])
                else:
                    args.append(None)
                             
        return tuple(qois), tuple(args)
           
    def add(self, name, val):
        if len(name)>0:
            if name=='OUTPUT_FIELDS':   
                self.addOutputField(val)  
            elif name=='POINTS_OF_INTEREST':
                self.addPointsOfInterest(val)
            elif name=='OUTPUT_QOI':
                self.addOutputQOI(val)
            else:
                setattr(self,name,val)
    
    def addOutputField(self,args):
            
        self.OUTPUT_FIELDS.append(tuple(args))
            
    def addOutputQOI(self,args):
            
        self.OUTPUT_QOI.append(tuple(args))
        
    def addPointsOfInterest(self,args):
        
        setname = args[0]
        points = args[1:]
        print setname, points
        for i,p in enumerate(points):
            if '(' in p:
                p = p.strip('(')
                p = p.strip(')')
                p = p.split(',')
                points[i] = tuple([round(float(pi),self.DECIMALS) for pi in p])
            else:
                points[i] = eval(p)
        
        self.POINTS_OF_INTEREST[setname] = points
        
    def getPointsOfInterest(self,set):
        
        return self.POINTS_OF_INTEREST[set]
    